/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.yczbj.ycvideoplayer.ability;

import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.Image;
import ohos.agp.components.StackLayout;
import ohos.agp.utils.Point;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayManager;
import ohos.multimodalinput.event.TouchEvent;

import com.yc.video.bridge.ControlWrapper;
import com.yc.video.config.ConstantKeys;
import com.yc.video.player.VideoPlayer;
import com.yc.video.ui.pip.CustomFloatController;
import com.yc.video.ui.view.BasisVideoController;

import org.yczbj.ycvideoplayer.ConstantVideo;
import org.yczbj.ycvideoplayer.ResourceTable;
import org.yczbj.ycvideoplayer.utils.ImageLoader;
import org.yczbj.ycvideoplayer.utils.JumpUtil;

/**
 * 4.1 页面悬浮可拖动小窗口播放视频
 *
 * @since 2021-05-10
 */
public class PipAbility extends BaseAbility {
    private VideoPlayer mVideoPlayer;
    private VideoPlayer mFloatVideoPlayer;
    private Button mBtnFloat;
    private StackLayout stackLayout;
    DependentLayout moveDirectionalLayout;
    private Image smallPlayerOpen;
    private Image smallPlayerClose;
    float startX = 0;
    float startY = 0;
    private int barHeight = 0;

    @Override
    protected int getLayoutResId() {
        return ResourceTable.Layout_ability_pip_video;
    }

    @Override
    protected void initComponent(Intent intent) {
        super.initComponent(intent);
        stackLayout = (StackLayout) findComponentById(ResourceTable.Id_stackLayout);
        mVideoPlayer = (VideoPlayer) findComponentById(ResourceTable.Id_player_container);
        mFloatVideoPlayer = (VideoPlayer) findComponentById(ResourceTable.Id_player_float);
        stackLayout = (StackLayout) findComponentById(ResourceTable.Id_stackLayout);
        mBtnFloat = (Button) findComponentById(ResourceTable.Id_btn_float);
        moveDirectionalLayout = (DependentLayout) findComponentById(ResourceTable.Id_moveDirectionalLayout);
        smallPlayerOpen = (Image) findComponentById(ResourceTable.Id_small_player_open);
        smallPlayerClose = (Image) findComponentById(ResourceTable.Id_small_player_close);
        initVideoPlayer();
        initFloatVideoPlayer();
        moveDirectionalLayout.setTouchEventListener(new MyTouchEventListener());
        ComponentContainer componentContainer = (ComponentContainer) mFloatVideoPlayer.getComponentAt(0);
        for (int i = 0; i < componentContainer.getChildCount(); i++) {
            componentContainer.getComponentAt(i).setTouchEventListener(new MyTouchEventListener());
        }
    }

    @Override
    protected void initListener() {
        super.initListener();
        mBtnFloat.setClickedListener(component -> {
            ComponentContainer.LayoutConfig layoutConfig = mVideoPlayer.getLayoutConfig();
            layoutConfig.height = 1;
            layoutConfig.width = 1;
            mVideoPlayer.setLayoutConfig(layoutConfig);
            mVideoPlayer.setScreenScaleType(ConstantKeys.PlayerScreenScaleType.SCREEN_SCALE_16_9);
            mVideoPlayer.setVisibility(Component.INVISIBLE);
            moveDirectionalLayout.setVisibility(Component.VISIBLE);
            mVideoPlayer.pause();
        });
        smallPlayerOpen.setClickedListener(component -> {
            moveDirectionalLayout.setVisibility(Component.HIDE);
            mFloatVideoPlayer.pause();
            JumpUtil.jumpToAbility(this, PipAbility.class);
        });
        smallPlayerClose.setClickedListener(component -> {
            moveDirectionalLayout.setVisibility(Component.HIDE);
            mFloatVideoPlayer.pause();
        });
    }

    private void initVideoPlayer() {
        ComponentContainer.LayoutConfig layoutConfig = mVideoPlayer.getLayoutConfig(); // 播放器居中
        layoutConfig.width = ComponentContainer.LayoutConfig.MATCH_PARENT;
        layoutConfig.height = ComponentContainer.LayoutConfig.MATCH_PARENT;
        mController = new BasisVideoController(this);
        Image thumb = mController.getThumb();
        // 设置视频背景图
        ImageLoader.loadImage(getContext(), ResourceTable.Media_image_default, thumb);
        // 设置控制器
        mVideoPlayer.setController(mController);
        mVideoPlayer.setDecorView(stackLayout);
        mVideoPlayer.setUrl(ConstantVideo.VideoPlayerList.get(0));
    }

    private void initFloatVideoPlayer() {
        CustomFloatController customFloatController = new CustomFloatController(this);
        mFloatVideoPlayer.setController(customFloatController);
        mFloatVideoPlayer.setUrl(ConstantVideo.VideoPlayerList.get(0));
    }

    @Override
    protected void onActive() {
        super.onActive();
        if (mVideoPlayer.getVisibility() == Component.VISIBLE) {
            mVideoPlayer.resume();
        }
        if (moveDirectionalLayout.getVisibility() == Component.VISIBLE) {
            mFloatVideoPlayer.resume();
        }
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        mVideoPlayer.pause();
        mFloatVideoPlayer.pause();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mVideoPlayer.release();
        mFloatVideoPlayer.release();
    }

    @Override
    protected void onBackPressed() {
        ControlWrapper.defaultValue();
        if (mVideoPlayer == null || !mVideoPlayer.onBackPressed()) {
            super.onBackPressed();
        }
    }

    class MyTouchEventListener implements Component.TouchEventListener {
        @Override
        public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
            // 计算出状态栏高度，防止抖动
            if (barHeight == 0) {
                barHeight = (int) (touchEvent.getPointerScreenPosition(touchEvent.getIndex()).getY()
                    - touchEvent.getPointerPosition(touchEvent.getIndex()).getY());
            }
            switch (touchEvent.getAction()) {
                case TouchEvent.PRIMARY_POINT_DOWN:
                    startX = touchEvent.getPointerPosition(touchEvent.getIndex()).getX();
                    startY = touchEvent.getPointerPosition(touchEvent.getIndex()).getY();
                    break;
                case TouchEvent.POINT_MOVE:
                    float x = touchEvent.getPointerScreenPosition(touchEvent.getIndex()).getX() - startX;
                    float y = touchEvent.getPointerScreenPosition(touchEvent.getIndex()).getY() - startY - barHeight;
                    ComponentContainer.LayoutConfig layoutConfig = moveDirectionalLayout.getLayoutConfig();
                    if (x < 0) x = 0;
                    int leftValue = getWidth() - component.getWidth();
                    if (x > leftValue) x = leftValue;
                    layoutConfig.setMarginLeft((int) x);
                    if (y < 0) y = 0;
                    int topValue = getHeight() - component.getHeight();
                    if (y > topValue) y = topValue;
                    layoutConfig.setMarginTop((int) y);
                    moveDirectionalLayout.setLayoutConfig(layoutConfig);
                    break;
                default:
                    break;
            }
            return true;
        }
    }

    /**
     * 获取屏幕宽度
     *
     * @return 屏幕宽度
     */
    public int getWidth() {
        Display display = DisplayManager.getInstance().getDefaultDisplay(this).get();
        Point point = new Point();
        display.getSize(point);
        return (int) point.getPointX();
    }

    /**
     * 获取屏幕高度，不包含状态栏的高度
     *
     * @return 屏幕高度，不包含状态栏的高度
     */
    public int getHeight() {
        Display display = DisplayManager.getInstance().getDefaultDisplay(this).get();
        Point point = new Point();
        display.getSize(point);
        return (int) point.getPointY();
    }
}
